class Cell{
//单个方格，坐标参数,墙壁显示
    int i,j;
    int step;//在第多少步被搜到，
    //每个cell包含四个boolean数组，表示上右下左墙壁是否存在
    boolean[] walls = new boolean[]{true,true,true,true};
                                   //上    右   下  左
    //boolean[] walls = new boolean[]{false,false,false,false};
    //只要有两个true且在横和竖行能看起来填满，因为一根线的位置会被画两次

    boolean visited = false;//当前方块未被访问过
    
  //  int draw_times = 1;

    ArrayList<Cell> neighbours;//储存邻居信息
    Cell previous = null;//

    Cell(int i,int j){//构造函数
        this.i = i;
        this.j = j;
    }

    void highlight() {//高亮展示
        noStroke( );//不画轮廓线
        fill(200,0,200);//填充？？的颜色
        rect(i * w,j * w,w,w);// https://processing.org/reference/rect_.html 当前方块背景用rect，大小w*w，颜色(200,0,200)
    }
    //用line展示墙壁，用colorc
    void show(color c){
        int x = i * w, y = j * w;
        strokeWeight(2);//调整为10个像素宽。
        strokeJoin(ROUND);//圆角//project 斜角
        strokeCap(SQUARE);
        //边的颜色
        stroke(wall_c );//设置用于在形状周围绘制线条和边框的颜色 一个参数就是灰度
        
        
        
        //从左上角逆时针绘制，上右下左
        int bias = 0;//---
        if (walls[0])line(x,y,x + w + bias,y);//两点之间绘制一条直线
        if (walls[1])line(x + w + bias,y,x + w+ bias,y + w + bias);//两点之间绘制一条直线
        if (walls[2])line(x + w + bias,y + w + bias,x,y + w + bias);//两点之间绘制一条直线
        if (walls[3])line(x,y + w + bias ,x ,y );//两点之间绘制一条直线
       
        
        
        
        noStroke();
        fill(c);
        rect(x ,y ,w,w);//展现小方块
        //rect(x + 10,y + 10,w,w);//直接设置成左上角x，y就行，偏移还是数组的偏移方式，x+就是向左，y+就是向下
        
        //前两个参数设置左上角的位置(在整个大图中的位置？)，第三个参数设置宽度，第四个参数设置高度

    }
    void addNeighbours() {
        neighbours = new ArrayList<Cell>();
        //加入
        if(!walls[0] && j > 0)//第二个判断保证不出界
          neighbours.add(grid[index(i,j - 1)]);
        
        if(!walls[1] && i < cols - 1)
          neighbours.add(grid[index(i + 1,j )]);
        
        if(!walls[2] && j < rows - 1)
          neighbours.add(grid[index(i,j + 1)]);
        
        if(!walls[3] && i > 0)
          neighbours.add(grid[index(i - 1,j)]);
        
        
        
    }



    int index(int i,int j){//坐标到一维grid
        if(i < 0 || i >= cols || j < 0 || j >= rows )return -1;

        return i + j * cols;
    }
      void backTrack(){//回溯路径
        
        ArrayList<Cell> path = new ArrayList<Cell>();
        Cell temp = this;//如果只用current回溯就只有当前路径而没有别的路径
        while(temp != null){
            path.add(temp);
            temp = temp.previous;
        }   
        
        if(findpath){
            boolean endTrack = false;
            
            
            strokeJoin(ROUND);
            stroke(#76ff03);
            strokeWeight(w / 2);//宽度,
            Cell track = current;//从最后点搜回起点
            noFill( );//不要那个点到源点的填充
            beginShape(  );//开始画一个图型，vertex用
            strokeWeight(w/2);
            //line (current.i * w + w / 2, current.j * w + w / 2,track.i * w + w / 2, track.j * w + w / 2);//   不用线是因为线中间有缝隙
            
            vertex(track.i * w + w / 2,track.j * w + w / 2);
            for(int n = 0; n < pathCount;  ++ n){//每次都多走1步,一直走到pathCount的最大值
                if(track != null){
                  vertex(track.i * w + w / 2,track.j * w + w / 2);
              
                  track = track.previous;
                }else{
                      println("SSSUCked");
                     endTrack = true;
                }
                
            }
            endShape( );
            pathCount ++;
         
            if(endTrack) {
              println("dist:" + (pathCount - 2 - 1));//减去起点终点多搜的和距离应该-1
              //noLoop();
              //drawFinish = true;
              delay(end_delay);
              
                 reset();
               
            }
             
            
            return ;
        }
        
        //正常在走的路径
        noFill( );//不填充，绘制边框还在 应该是
       
        //路径颜色
        stroke(inner_path_c);//如果还没有完整路径，就以当前位置把瞬时路径用黄色标出来
        strokeWeight(w / 2);
        beginShape(  );//开始画一个图型
        for(int i = 0; i < path.size(); ++ i){
            vertex(path.get(i).i * w + w / 2,path.get(i).j * w + w / 2);
        }
        endShape(  );
        strokeWeight(2);

    }

    Cell checkNeighbours() {//检测周围邻居，随机返回一个。没有返回NULL

        ArrayList<Cell> around = new ArrayList<Cell>();//存存在的邻居
        
        int top = index(i,j - 1);//上面一个，j-1
        int right = index(i + 1,j );
        int bottom = index(i,j + 1);
        int left = index(i - 1,j);

        if(top != -1 && !grid[top].visited)//存在且没被访问过，加入
            around.add(grid[top]);
        if(right != -1 && !grid[right].visited)//存在且没被访问过，加入
            around.add(grid[right]);
        if(bottom != -1 && !grid[bottom].visited)//存在且没被访问过，加入
            around.add(grid[bottom]);
        if(left != -1 && !grid[left].visited)//存在且没被访问过，加入
            around.add(grid[left ]);
        
        if(around.size() > 0){
            int r = (int) random(around.size());//从around中随机挑一个边
            return around.get(r);//get就是安全的下标访问。返回r邻居
        }
        return null;
    }
}
